/**
 * @file mvs_factory_tool.h
 * @author your name (you@domain.com)
 * @brief 本库作为MVS DEV SDK的厂测补充部分，提供厂测相关配置、测试动作功能等中转
 *        独立成库的架构目的为分离厂测环境和用户环境；
 *        所以强烈建议用户环境固件不要包含和链接本库
 * @version 0.1
 * @date 2022-10-13
 * 
 * @copyright Copyright (c) 2022
 * 
 */

#ifndef __MVS_FACTORYTOOL_H__
#define __MVS_FACTORYTOOL_H__

#include "mvdef.h"

MVCXX_EXTERN_BEGIN

typedef enum _factory_tool_spec_type
{
    MVS_FT_SPEC_NONE  = 0,
    MVS_FT_SPEC_HS    = 1,  ///< reserve
    MVS_FT_SPEC_MIIOT = 2,  ///< MiHome
    MVS_FT_SPEC_SLW   = 3,  ///< CMobileNet-SLW(QianLiYan)
}mvs_ft_spec_e;

typedef struct _factory_tool_args {
    mv_cv8ptr_t cpv8_sdcard_root;  ///< TF卡根目录（无TF卡槽，则置NULL或""）
    mv_cv8ptr_t cpv8_model_name;   ///< 设备model名称
    mv_cv8ptr_t cpv8_product_name; ///< 设备product名称
    mv_cv8ptr_t cpv8_spec_data;    ///< 特定设备非固定协议数据(可见字符串，且限定长度1262)
    mv_u16_t    u16_spec_len;      ///< 特定设备非固定协议数据长度
    mv_u8_t     u8_spec_type;      ///< 特点设备非固定协议类型[mvs_ft_spec_e]
}mvs_ft_args_t;
/**
 * @brief 厂测API初始化
 * 
 * @param pargs  [in] 厂测工具驱动参数
 * @return 初始化结果
 * - success : MV_EC_SUCCESS
 * -  failed : MV_EC_MALLOC_FAILED
 * @note 只要有链接厂测库，都可以调用此接口初始化，可以启用在线厂测参数配置功能
 */
mv_s32_t mvs_factory_tool_init(mvs_ft_args_t *pargs);
/**
 * @brief 厂测配置加载
 * 
 * @param pargs  [in] 厂测工具驱动参数
 * @return 加载结果 
 * - success : MV_EC_SUCCESS
 * -  failed : MV_EC_IGNORE  (不存在厂测配置文件)
 *             else
 * 
 * @note 在"mvs_factory_tool_start"前调用，必须在"mvs_service_init"前调用
 */
mv_s32_t mvs_factory_tool_cfg_load(mvs_ft_args_t *pargs);
/**
 * @brief 厂测工具启动
 * 
 * @param pargs  [in] 厂测工具驱动参数
 * @return 初始化结果
 * - success : MV_EC_SUCCESS
 * -  failed : MV_EC_IGNORE  (不存在厂测工具文件)
 *             else
 * 
 * @note 初始化接口会根据给定的TF卡根目录，读取校验厂测客户端生成的配置文件，
 *       校验成功时，会自动设定MV DEV SDK为厂测模式，部分功能会受限，
 *       以及厂测专属功能会启用；
 * @note 当pargs->cpv8_sdcard_root表示无卡槽设备时，调用此接口会触发无卡槽厂测流程，
 *       阻塞等待网络状态 = STA/ETH（局域网） 或 LTE（互联网）
 *       然后配合厂测工装，从对应网络获取到合法厂测配置后，接口才会返回
 * @note 需要在"mvs_iotc_service_init"成功后调用
 */
mv_s32_t mvs_factory_tool_start(mvs_ft_args_t *pargs);

typedef enum _factory_tool_config_code
{
    /****************/
    /** 字符型配置类 */
    /****************/
    CFG_PRODUCT = 0,           ///< 产品名称(32字节字符串，含'\0')

    /****************/
    /** 数值型配置类 */
    /****************/
    CFG_LENS_TYPE,             ///< 镜头类型[0=普通, 1=180°全景, 2=360°全景]
    /*******/
    CFG_SPK_VOL_DEFAULT,       ///< 扬声器硬件音量出厂默认值[1,100]
    CFG_SPK_VOL_MAX_LIMIT,     ///< 扬声器硬件音量最大值限制[1,100](0=不支持喇叭)
    CFG_SPK_VOL_MIN_LIMIT,     ///< 扬声器硬件音量最小值限制[1,100]
    CFG_MIC_VOL_DEFAULT,       ///< 麦克风硬件音量出厂默认值[1,100]
    CFG_MIC_VOL_MAX_LIMIT,     ///< 麦克风硬件音量最大值限制[1,100](0=不支持麦克风)
    CFG_MIC_VOL_MIN_LIMIT,     ///< 麦克风硬件音量最小值限制[1,100]
    CFG_PT_H_CNT,              ///< 水平云台数量[0,1,2,...]
    CFG_PT_V_CNT,              ///< 垂直云台数量[0,1,2,...]
    CFG_PT_H_REVERSAL,         ///< 云台水平反转（硬件；参考基准：保持人眼与镜头朝向同向，定义左转：镜头从朝向轴线往左转动，右转：镜头从朝向轴线往右转动）
    CFG_PT_V_REVERSAL,         ///< 云台垂直反转（硬件；参考基准：保持人眼与镜头朝向同向，定义上转：镜头从朝向轴线往上转动，右转：镜头从朝向轴线往下转动）
    CFG_PT_H_SPEED_MAX_LIMIT,  ///< 云台水平速度最大值限制（适配外壳最大可稳定转动的速度限制，[1,100]）
    CFG_PT_V_SPEED_MAX_LIMIT,  ///< 云台垂直速度最大值限制（适配外壳最大可稳定转动的速度限制，[1,100]）
    /*******/
    CFG_IRCUT_REVERSAL,        ///< IRCUT反相控制[0,1]
    CFG_HARDIRF_REVERSAL,      ///< 硬光敏检测电平反相[0,1]
    CFG_IRLED_EN_LEVEL,        ///< 红外灯使能电平[0,1]
    CFG_WLED_EN_LEVEL,         ///< 白光灯使能电平[0,1]
    /*******/
    CFG_BAT_SUPPORT,           ///< 电池相关功能支持[0=不支持；1=支持]
    CFG_BAT_SOC_ADC_MIN,       ///< 电池电量ADC检测最低数值（比实际最低电压稍低一点，保证能兼容电池个体差异不至于出现接上电池有0%电量情况）
    CFG_BAT_SOC_ADC_MAX,       ///< 电池电量ADC检测最高数值（比实际最高电压稍低一点，保证能兼容电池个体差异达到100%计算）
    /*******/
    CFG_ONVIF_CTRL,            ///< APP显示onvif功能[0=不显示/不支持, 1=显示/支持]
    CFG_ONVIF_DEFAULT,         ///< Onvif开关默认值(0=默认关闭；1=默认开启)
    CFG_BINDING_SUPPORT,       ///< 支持绑定方式([abl_binding_bmpc32_e];多选,多个通道+校验方式)
    CFG_BINDING_PREFS,         ///< 首选绑定方式([abl_binding_bmpc32_e];单选,一个通道+校验方式)
    /*******/
    CFG_SDCARD_FMT_CHECK,      ///< SD卡检查功能[0，1]，默认为1
    CFG_REC_VQLT_DEFAULT,      ///< 录像质量出厂默认值[1=SD, 2=HD, 4=FHD]
    /*******/
    CFG_PROMPT_LANGUAGE,       ///< 提示音语言[0,1,2,...]
    /*******/
    CFG_IMG_REVERSAL,          ///< 图像镜像翻转[0，1]
    CFG_COLOR_MODE_SUPPORT,    ///< 图像设置功能支持（白天/夜视模式手动切换）; [0=不支持； 1=支持]
    CFG_COLOR_MODE_DEFAULT,    ///< 图像设置功能出厂模式[0=自动, 1=夜视, 2=白天]（配合support=0，可以做到强制锁白天或夜视，且用户无法控制切换的效果）
    CFG_IRFM_MODE,             ///< 测光模式[0=软测光（默认）, 1=硬测光, 2=混合（不推荐)]
    CFG_LED_TYPE,              ///< 灯控类型[0=无灯, 1=纯红外灯, 2=纯白光灯, 3=红外+白光双灯]
    /*******/
    CFG_PT_H_VIRTUAL_LIMIT,    ///< 云台水平限位值
    CFG_PT_V_VIRTUAL_LIMIT,    ///< 云台垂直限位值
    CFG_PT_H_CENTER,           ///< 云台水平限位值中心
    CFG_PT_V_CENTER,           ///< 云台垂直限位值中心
    CFG_PT_H_STEP_UNIT,        ///< 云台水平步进距离值(越大越长，一般带齿轮硬件需要调整)
    CFG_PT_V_STEP_UNIT,        ///< 云台垂直步进距离值(越大越长，一般带齿轮硬件需要调整)
    CFG_PT_MT_AUTH,            ///< 云台运动跟踪能力[0=不支持；1=支持]
    CFG_PT_MT_H_STEP_UNIT,     ///< 云台运动跟踪水平步进距离值(越大越长，一般带齿轮硬件需要调整)
    CFG_PT_MT_V_STEP_UNIT,     ///< 云台运动跟踪垂直步进距离值(越大越长，一般带齿轮硬件需要调整)
    /*******/
    CFG_ISP_CUSTOM,            ///< ISP厂家定制参数组[0=默认,1,2,...]
    CFG_ISP_PATCH,             ///< ISP机型补充参数[0=默认,1,2,...]

    /****************/
    /** 对象型配置类 */
    /****************/
    CFG_PCBA,                  ///< 硬件pcba检测功能
    CFG_GPIO,                  ///< 硬件各用途gpio具体配置
    /*******/
    CFG_CUSTOM_OSD,            ///< 自定义osd配置
    /***************/

    /*******/
    CFG_CODE_MAX,
}ftool_cfg_code_e;

/** 测试动作 */
typedef enum _factory_tool_test_action_code
{
    TEST_COLOR,                ///< 画面测试（switch:彩色=0/黑白=1）= in:{"switch":0}
    TEST_SPEAKER,              ///< 音频播放（播放提示音） = in:{}
    TEST_IRCUT,                ///< IRCUT切换测试（switch:白天=0/晚上=1）= in:{"switch":0}
    TEST_PD,                   ///< 光敏测试（读取测量值、双向阈值） = in:{}; out:{"cur":123, "DayThr":800, "NightThr": 100}
    TEST_LED,                  ///< 灯切换测试（type:红外灯=0，白光灯=1；switch：开=0/关=1） = in:{"type":0, "switch":0}
    TEST_RESET,                ///< 复位按键测试（检测按键按下3秒，比正常复位短；响应，并复位）
    TEST_PANO_PARAM,           ///< 全景切图测试(lens:全景类型，普通=0，180°=1，360°=2；高清通道为参照)
                               ///< in:{"pano_cropx":540, "pano_y":540, "pano_r":544} (需要修改哪个参数，就传入哪个)
                               ///< out:{"lens":2, "pano_cropx_max":200, "pano_cropx":100, "pano_y":540, "pano_r":544} （返回实时变更值）
                               ///< (180°参数：pano_x:水平偏移pxl，pano_y:垂直偏移pxl，pano_r:半径pxl；)
                               ///< (360°参数：pano_cropx_max:水平裁切最大偏移pxl, pano_cropx:水平裁切偏移pxl，pano_y:垂直偏移pxl，pano_r:半径pxl；)
    TEST_WIFI,                 ///< 强制触发WiFi连接厂测模式指定的路由，进行WiFi测试
    TEST_NETMODULE,            ///< 网络模块测试（在不断开当前主测试网络情况下，测试指定网络模块是否正常）
                               ///< 1-1、获取测试状态 = "in":{"type": 3, "act": 1} (type: WiFi=1，LTE4G=2，ETH=3；act: 获取状态=1，开始测试=2）
                               ///< 1-2、测试状态响应 = "out":{"state": 1, "timeout": 60} (state: 不支持=0，空闲=1，测试中=2；timeout: 测试需求超时时间，秒）
                               ///< 2-1、测试开始请求 = "in":{"type": 3, "act": 2} (type: WiFi=1，LTE4G=2，ETH=3；act: 获取状态=1，开始测试=2）
                               ///< 2-2、测试完成响应 = "out":{"code": 1} (code: 1 = 正常; 2 = 无SIM; 3 = 无法连接网络; 4 = 模块异常）
                               ///< 流程：工装发送1-1测试状态获取，设备响应1-2结果；根据结果，决定请求2-1开始测试，阻塞等待设备返回2-2结果，默认超时1分钟（1-2返回timeout值，则以设备为准）
    TEST_BUTTON,               ///< 通用按键测试 = "in":{"btid": 1} 等待按键返回；（btid: 按键序号[1, ...]）
}ftool_act_code_e;

typedef enum _factory_tool_value_type
{
    FTOOL_VT_INVALID = 0,
    FTOOL_VT_BOOL    = 1,
    FTOOL_VT_NUMBER,
    FTOOL_VT_FLOAT,
    FTOOL_VT_STRING,
    FTOOL_VT_ARRAY,
    FTOOL_VT_OBJECT,
}ftool_vt_e; ///< (与mvt_sjson.h的mvt_djson_vtype_e定义一致)

typedef struct _factory_tool_config_ctx
{
    union {
        mv_s64_t     s64_number; ///< 数值型value  ：integer number
        mv_bool_t    bl_bool;    ///< 布尔型value  ：MV_TRUE / MV_FALSE
        mv_v8ptr_t   pv8_string; ///< 字符串型value："\"...\""
        mv_cv8ptr_t cpv8_string; ///< （只读，输入类）
        mv_v8ptr_t   pv8_object; ///< 对象型value  ："{...}"
        mv_cv8ptr_t cpv8_object; ///< （只读，输入类）
        mv_v8ptr_t   pv8_array;  ///< 数组型value  ："[]"
        mv_cv8ptr_t cpv8_array;  ///< （只读，输入类）
    };
    mv_u32_t u24_vlen_max:24;  ///< value缓冲区大小
    mv_u32_t u8_type:8;        ///< value类型
}ftool_cfg_ctx_t;

/**
 * @brief 厂测设备配置重置接口
 * 
 * @return 重置操作结果
 * - success : MV_EC_SUCCESS
 * -  failed : else
 * 
 * @note 一般因product_id不一致，导致需要重置之前的厂测配置，重新应用新的配置而调用
 */
mv_s32_t mvspt_factory_tool_cfg_reset();
/**
 * @brief 厂测设备配置获取接口
 * 
 * @param s32_cfg_code  [in] 配置项代号[ftool_cfg_code_e]
 * @param pst_out      [out] 配置项内容
 * @return 应用结果
 * - success : >= 0 （返回value长度）
 * -  faield : MV_EC_NOT_SUPPORT (不支持此项)
 *             else
 */
mv_s32_t  mvspt_factory_tool_cfg_pick(mv_s32_t s32_cfg_code, ftool_cfg_ctx_t *pst_out);
/**
 * @brief 厂测设备配置应用接口
 * 
 * @param s32_cfg_code [in] 配置项代号[ftool_cfg_code_e]
 * @param pst_out      [in] 配置项内容
 * @param bl_flush     [in] 是否立即刷新（辅助判断，多条并发时可减少写配置次数）
 * @return 应用结果
 * - success : MV_EC_SUCCESS
 * -  faield : MV_EC_NOT_SUPPORT (不支持此项)
 *             else
 * 
 * @note 特别的，cpv8_key="CFG_PRODUCT"时，表示配置有新的productname需要应用
 */
mv_s32_t  mvspt_factory_tool_cfg_apply(mv_s32_t s32_cfg_code, ftool_cfg_ctx_t *pst_in, mv_bool_t bl_flush);
/**
 * @brief 厂测设备测试动作处理接口
 * 
 * @param s32_act_code [in] 动作项代号[ftool_act_code_e]
 * @param cpv8_in      [in] 动作项内容
 * @param s32_inlen    [in] 动作项内容长度
 * @param pout         [out]动作项响应结果缓冲区
 * @param s32_outmax   [in] 动作项响应结果缓冲区大小
 * @return 处理结果
 * - success : >=0 响应结果数据长度
 * -  failed : else [mvdef_ec_e] 
 */
mv_s32_t  mvspt_factory_tool_action(mv_s32_t s32_act_code, mv_cv8ptr_t cpv8_in, mv_s32_t s32_inlen, mv_vptr_t pout, mv_s32_t s32_outmax);
/**
 * @brief 厂测设备授权信息烧录处理接口
 * 
 * @param u32_did   [in]  请求授权DID
 * @param pv8_token [in]  请求授权访问凭证
 * @param ppv8_msg  [out] 处理结果描述（主要用于返回elic库的msg；由caller释放，请申请使用普通的堆内存）
 * @return 处理结果
 * - success : MV_EC_SUCCESS
 * -  failed : else [mvdef_ec_e]
 * 
 * @note 实现端需要使用mvs_elic库完成授权过程
 */
mv_s32_t  mvspt_factory_tool_elice_auth(mv_u32_t u32_did, mv_v8ptr_t pv8_token, mv_v8ptr_t *ppv8_msg);
/**
 * @brief 厂测设备WiFi连接接口（临时，不需要保存配置信息）
 * 
 * @param pv8_sta_ssid [in] 目标WiFi名称
 * @param pv8_sta_pwd  [in] 目标WiFi密码
 * @return 操作结果
 * - success : MV_EC_SUCCESS
 * -  failed : MV_EC_FAILED
 */
mv_s32_t  mvspt_factory_wifi_config(mv_v8ptr_t pv8_sta_ssid, mv_v8ptr_t pv8_sta_pwd);
/**
 * @brief 厂测设备BLE测试接口（临时，不需要保存配置信息）
 * 
 * @param u8_mode     [in] 测试方法(0=广播，待被连接；1=主动连接)
 * @param pv8_name    [in] 广播/连接指定名称
 * @param u32_timeout [in] 测试超时时间（秒；0=无超时）
 * @return 操作结果
 * - success : MV_EC_SUCCESS
 * -  failed : MV_EC_NOT_SUPPORT (不支持蓝牙)
 *             MV_EC_FAILED (测试失败)
 *             MV_EC_INVALID_ARGS (参数不合法或不适用)
 * 
 * @note “连接”或“被连接”测试，用于初步测试BLE功能是否正常；此测试接口，需要测试完成后才返回退出
 */
mv_s32_t  mvspt_factory_ble_test(mv_u8_t u8_mode, mv_v8ptr_t pv8_name, mv_u32_t u32_timeout);

MVCXX_EXTERN_END

#endif